#include <iostream>

using namespace std;
/*
	重写和重载：
		1、如果子类只重写了 父类virtual重载方法中的一个 -- 那么父类该方法的其他版本将被子类所隐藏
		2、子类重写的父类 virtual重载方法，不能改变返回值类型 -- 否则编译不通过
*/
class Base {
public:
	// 发生了重载
	virtual int f() const {cout<<"Base::f()\n";return 1;}
	virtual void f(string) const {}
	
	virtual void g() const {}
};

class Derived1 : public Base {
public: 
	void g() const {}
};

class Derived2 : public Base {
public: 
	// Overriding 
	int f() const {cout<<"Derived2::f()\n"; return 2;}
};

class Derived3 : public Base {
public: 
	// 子类重写的父类 virtual重载方法，不能改变返回值类型 -- 否则编译不通过
	//! void f() const{ cout << "Derived3::f()\n";}
};

class Derived4 : public Base {
public:
	int f(int) const { 
		cout << "Derived4::f()\n"; 
		return 4;
	} // Change argument list
};

int main(int argc, char *argv[]) {
	string s("hello");
	
	//子类未重写 基类的virtual重载方法，可以继承父类的所有重载方法
	Derived1 d1;
	int x = d1.f();
	d1.f(s);
	
	//子类重写了 某个版本的基类的virtual重载方法，其他版本将被隐藏
	Derived2 d2;
	x = d2.f();
	//! d2.f(s); // string version hidden
	
	//子类写了 基类的virtual重载方法的一个全新版本 -- 基类中所有重载方法都将被隐藏
	Derived4 d4;
	x = d4.f(1);
	//! x = d4.f(); // f() version hidden
	//! d4.f(s); // string version hidden
	
	//向上转型，用的是基类的虚方法表 -- 子类中全新的方法将无法使用
	Base& br = d4; // Upcast
	//! br.f(1); // Derived version unavailable
	br.f(); // Base version available
	br.f(s); // Base version abailable
}